home
***
CD-ROM
|
disk
|
FTP
|
other
***
search
/
MACD 5
/
MACD 5.bin
/
workbench
/
boot
/
czesc_1
/
breq
/
breq.c
< prev
next >
Wrap
C/C++ Source or Header
|
1994-09-09
|
16KB
|
522 lines
/******************************************************************************
* *
* BReq: opens a window on a custom screen with two gadgets for a startup *
* option selection. Originally intended for use with NetBSD-Amiga. *
* *
* Copyright (c)1994 by Eric R. Augustine (voodoo@well.sf.ca.us) *
* *
* This is Copyrighted FreeWare so you may do with it as you wish as long as *
* any distribution contains all original sources and documentation and that *
* distribution is not done for the purpose of profitable gains. The author *
* accepts no responsibility for any damage as a result of the use of this *
* program nor does he make any claims or garantees as to what this program *
* can do. *
* *
******************************************************************************/
#include <graphics/gfxbase.h>
#include <proto/intuition.h>
#include <proto/dos.h>
#include <proto/exec.h>
#include <proto/graphics.h>
#include <stdlib.h>
#include <string.h>
#define TRUE 1
#define FALSE 0
#define PALHEIGHT 512
#define PALGADTOP 56
/* these two for action based on user response or timeout
*/
#define SYSA 1
#define SYSB 2
/* yes I know there's already a type BOOL
*/
typedef int bool;
/* library bases needed for closing the libraries at cleanup
*/
struct IntuitionBase *IntuitionBase;
extern struct GfxBase *GfxBase;
struct Library *DosBase;
/* build blank screen pointer
*/
USHORT chip BlankPoint[4] = {
0x0000, 0x0000,
0x0000, 0x0000
};
/* create gadget box: makes a beveled box 96 pixels wide by
* 32 pixels high.
*/
SHORT BoxPoints[] = {
0, 0,
96, 0,
96, 32,
0, 32,
0, 0,
4, 4,
92, 4,
96, 0,
92, 4,
92, 28,
96, 32,
92, 28,
4, 28,
0, 32,
4, 28,
4, 4
};
/* make gadget borders from boxes
*/
struct Border BRBorder = {
0, /* LeftEdge */
0, /* TopEdge */
1, /* FrontPen */
0, /* BackPen */
JAM1, /* DrawMode */
16, /* Count */
BoxPoints, /* XY */
NULL, /* NextBorder */
};
/* build left gadget
*/
UBYTE BRLeftString[] = "A";
struct IntuiText BRLeftText = {
1, /* FrontPen */
0, /* BackPen */
JAM1, /* DrawMode */
8, /* LeftEdge */
12, /* TopEdge */
NULL, /* ITextFont */
BRLeftString, /* IText */
NULL /* NextText */
};
struct Gadget BRLeftGad = {
NULL, /* NextGadget */
50, /* LeftEdge */
157, /* TopEdge */
96, /* Width */
32, /* Height */
GADGHCOMP, /* Flags */
GADGIMMEDIATE| /* Activation */
RELVERIFY,
BOOLGADGET, /* GadgetType */
(APTR)&BRBorder, /* GadgetRender */
NULL, /* SelectRender */
&BRLeftText, /* GadgetText */
NULL, /* MutualExclude */
NULL, /* SpecialInfo */
0, /* GadgetID */
NULL /* UserData */
};
/* build comment string for left button
*/
UBYTE BRLeftComment[] = " ";
struct IntuiText BRLeftCommentText = {
1, /* FrontPen */
0, /* BackPen */
JAM1, /* DrawMode */
8, /* LeftEdge */
12, /* TopEdge */
NULL, /* ITextFont */
BRLeftComment, /* IText */
NULL /* NextText */
};
/* build right gadget
*/
UBYTE BRRightString[] = "B";
struct IntuiText BRRightText = {
1, /* FrontPen */
0, /* BackPen */
JAM1, /* DrawMode */
8, /* LeftEdge */
12, /* TopEdge. */
NULL, /* ITextFont */
BRRightString, /* IText */
NULL /* NextText */
};
struct Gadget BRRightGad = {
&BRLeftGad, /* NextGadget */
50, /* LeftEdge */
210, /* TopEdge */
96, /* Width */
32, /* Height */
GADGHCOMP, /* Flags */
GADGIMMEDIATE| /* Activation */
RELVERIFY,
BOOLGADGET, /* GadgetType */
(APTR)&BRBorder, /* GadgetRender */
NULL, /* SelectRender */
&BRRightText, /* GadgetText */
NULL, /* MutualExclude */
NULL, /* SpecialInfo */
0, /* GadgetID */
NULL /* UserData */
};
/* build comment string for right button
*/
UBYTE BRRightComment[] = " ";
struct IntuiText BRRightCommentText = {
1, /* FrontPen */
0, /* BackPen */
JAM1, /* DrawMode */
8, /* LeftEdge */
12, /* TopEdge */
NULL, /* ITextFont */
BRRightComment, /* IText */
NULL /* NextText */
};
/* BReq's window
*/
struct Window *BRWin;
/* Vanilla required new window
*/
struct NewWindow NWin = {
0, /* LeftEdge */
0, /* TopEdge */
640, /* Width */
400, /* Height */
0, /* DetailPen */
1, /* BlockPen */
CLOSEWINDOW| /* IDCMPFlags */
INTUITICKS|
GADGETDOWN|
VANILLAKEY|
MOUSEBUTTONS|
MOUSEMOVE,
WFLG_SMART_REFRESH| /* Flags */
WFLG_BORDERLESS|
RMBTRAP|
REPORTMOUSE|
ACTIVATE,
&BRRightGad, /* FirstGadget */
NULL, /* CheckMark */
NULL, /* Title */
NULL, /* Screen */
NULL, /* BitMap */
0, /* MinWidth */
0, /* MinHeight */
640, /* MaxWidth */
400, /* MaxHeight */
CUSTOMSCREEN /* Type */
};
/* BReq's custom screen
*/
struct Screen *BScreen;
/* new screen structure - could use OpenScreenTags()
* but, I want to account for PAL modes as well.
*/
struct NewScreen NScreen = {
0, /* LeftEdge */
0, /* TopEdge */
640, /* Width */
400, /* Height */
4, /* Depth */
0, /* DetailPen */
1, /* BlockPen */
HIRES|LACE, /* ViewModes */
CUSTOMSCREEN, /* Type */
NULL, /* Font */
NULL, /* DefaultTitle */
NULL, /* Gadgets */
NULL /* CustomBitMap */
};
/* readargs structure for user preferences
*/
struct internal_args {
char *timeout; /* idle time timeout */
char *blank; /* idle time blank screen */
const char *defresponse; /* select default for timeout */
char *buttons; /* title individual buttons */
bool reverse; /* reverse colors */
char *atext; /* itext to left button */
char *btext; /* itext to right button */
char *sysa; /* system call string top */
char *sysb; /* system call string bottom */
};
/* avoid larger stdio code by using this very simple printing routine
* using just dos library routines and string.
*/
void error(char *errstr) {
Write(Output(),errstr,strlen(errstr));
}
main(int argc, char *argv[]) {
APTR address; /* IDCMP response address for gadgets */
bool user_response = FALSE; /* whether or not user has made a response */
bool BLANKDONE = FALSE; /* blanker currently in process */
char *buttonstr; /* modifiable button titles for user */
int action; /* action to take once BReq closes */
int hmode = 0; /* height of comments based on display */
ULONG class; /* IDCMP message Class */
ULONG seconds; /* Seconds counted by IDCMP */
ULONG startsecs; /* seconds at start of BReq */
ULONG blanksecs; /* seconds to blank */
ULONG blank_start; /* same as startsecs until blank */
ULONG user_secs; /* modifiable timeout value */
USHORT code; /* IDCMP keycodes via VANILLAKEY */
struct IntuiMessage *BRMessage; /* BReq's IDCMP Message port */
void CleanUp(void); /* close screen and libraries */
/* init command line args
*/
struct internal_args ia = { "31536000", /* timeout, one year */
"180", /* blank, three minutes */
"A", /* defresponse, bottom gadget */
"NetBSD|AmigaOS", /* buttons, titles */
FALSE, /* reverse, reverse */
" ", /* atext, top comment */
" ", /* btext, bottom comment */
"sys:loadbsd sys:vmunix -a", /* sysa, load NetBSD */
NULL }; /* sysb, no task */
/* open libraries
*/
if(!(DosBase = (struct Library *)OpenLibrary("dos.library",0))) {
error("BReq: can't open dos.library\n");
exit(1);
}
if(!(IntuitionBase = (struct IntuitionBase *)OpenLibrary("intuition.library",0))) {
error("BReq: can't open intuition.library\n");
exit(1);
}
if(!(GfxBase = (struct GfxBase *)OpenLibrary("graphics.library",0))) {
error("BReq: can't open graphics.library\n");
exit(1);
}
/* get user preferences: use AmigaOS RDArgs rather than C standard.
*/
(struct RDArgs *)ReadArgs("TIMEOUT/K,BLANK/K,DEFAULT/K,BUTTONS/K,REVERSE/S,ATEXT/K,BTEXT/K,SYSA/K,SYSB/K", (long *)&ia, NULL);
/* get current system seconds from intuition
*/
CurrentTime(&startsecs,NULL);
/* copy starting seconds for blanker
*/
blank_start = startsecs;
/* check for user specified default response: compare the character (string)
* from the command line with the acceptable values. if failure then use
* internal default value.
*/
if((strcmp(ia.defresponse,"A") == 0) || (strcmp(ia.defresponse,"a") == 0))
action = SYSA;
else if((strcmp(ia.defresponse,"B") == 0) || (strcmp(ia.defresponse,"b") == 0))
action = SYSB;
else {
error("BReq: invalid DEFAULT \"");
error((char *)ia.defresponse);
error("\", using \"A\".\n");
action = SYSA;
}
/* get timeout value: for some reason the intuitive way of doing this direct
* from the command line didn't work so using atoi() (clib) to do the job.
*/
user_secs = atoi(ia.timeout);
blanksecs = atoi(ia.blank);
/* make gadget titles. use routines from clib (defined in string.h) to get
* individual gadgets from one string. (using "|" for compatibility to 1.12)
*/
if(strstr(ia.buttons,"|") == NULL)
error("BReq: \"|\" separater missing, using default gadgets.\n");
else {
BRLeftText.IText = strtok(ia.buttons,"|");
buttonstr = strchr(ia.buttons,'|');
BRRightText.IText = strtok(buttonstr,NULL);
}
/* make gadget comments
*/
BRLeftCommentText.IText = ia.atext;
BRRightCommentText.IText = ia.btext;
/* check for PAL screen mode and set screen, window and
* gadgets accordingly.
*/
if(GfxBase->DisplayFlags & PAL) {
NScreen.Height = PALHEIGHT;
NWin.Height = PALHEIGHT;
BRLeftGad.TopEdge = PALGADTOP + 157;
BRRightGad.TopEdge = PALGADTOP + 210;
hmode = PALGADTOP;
}
/* do gui: open the screen then the window on which the gadgets are drawn.
* use IDCMP to count passing seconds and get user response, if any. set
* action value based on user response or execute default on timeout.
*/
if(!(BScreen = OpenScreen(&NScreen))) {
error("BReq: can't open screen\n");
exit(2);
}
/* if user wants reverse screen just switch bits. for white, 11 was used
* instead of 15 (brightest) since 15 was too bright.
*/
if(ia.reverse) {
SetRGB4(&BScreen->ViewPort,1,11,11,11);
SetRGB4(&BScreen->ViewPort,0,0,0,0);
}
else {
SetRGB4(&BScreen->ViewPort,1,0,0,0);
SetRGB4(&BScreen->ViewPort,0,8,9,9);
}
/* set the window's screen to the CUSTOMSCREEN
*/
NWin.Screen = BScreen;
/* open BReq's window
*/
if(!(BRWin = (struct Window *)OpenWindow(&NWin))) {
error("BReq: can't open window\n");
CloseLibrary((struct Library *)IntuitionBase);
CloseLibrary((struct Library *)DosBase);
CloseLibrary((struct Library *)GfxBase);
CloseScreen(BScreen);
exit(3);
}
/* write button comments to window
*/
PrintIText(BRWin->RPort,&BRLeftCommentText,150,hmode + 157);
PrintIText(BRWin->RPort,&BRRightCommentText,150,hmode + 210);
/* event loop: Wait() for message signals and take action based on Class
* of IDCMP message.
*/
while(!(user_response)) { /* wait for response or timeout */
Wait( 1 << BRWin->UserPort->mp_SigBit ); /* listen for IDCMP messages */
while(BRMessage = (struct IntuiMessage *)GetMsg(BRWin->UserPort)) {
if(BRMessage) {
class = BRMessage->Class; /* IDCMP response flag */
address = BRMessage->IAddress; /* response address */
seconds = BRMessage->Seconds; /* keep track of passing time */
code = BRMessage->Code; /* key code here */
ReplyMsg((struct Message *)BRMessage); /* don't keep Intui waiting */
switch(class) { /* what sort of response? */
case INTUITICKS: /* timer blank and timeout */
if(((int)(seconds - startsecs)) >= user_secs) {
user_response = TRUE; /* user response not before timeout */
}
else if((((int)(seconds - blank_start)) >= blanksecs) /* compare to blank delay */
&& (BLANKDONE == FALSE)) { /* and if screen not blank */
SetRGB4(&BScreen->ViewPort,1,0,0,0); /* blank background */
SetRGB4(&BScreen->ViewPort,0,0,0,0); /* blank text */
SetPointer(BRWin,BlankPoint,0,0,0,0); /* blank pointer */
BLANKDONE = TRUE; /* screen is blank */
}
break;
case GADGETDOWN: /* user pressed gadget */
user_response = TRUE;
if(address == (APTR)&BRLeftGad) /* get which gadget */
action = SYSA;
else
action = SYSB;
break;
case MOUSEMOVE: case MOUSEBUTTONS: /* user used mouse */
if(BLANKDONE) { /* if screen blank then unblank */
if(ia.reverse)
SetRGB4(&BScreen->ViewPort,1,11,11,11);
else {
SetRGB4(&BScreen->ViewPort,1,0,0,0);
SetRGB4(&BScreen->ViewPort,0,8,9,9);
}
ClearPointer(BRWin); /* and bring back pointer */
}
BLANKDONE = FALSE; /* screen no longer blank */
blank_start = (int)seconds; /* reset blanker timer */
break;
case VANILLAKEY: /* user hit keys */
if((code == 'v') || (code == 'y')) {
user_response = TRUE; /* user wants left gadget */
action = SYSA;
}
else if((code == 'b') || (code == 'n')) {
user_response = TRUE; /* user wants right gadget */
action = SYSB;
}
else if(code == 13) /* ASCII RETURN */
user_response = TRUE; /* user wants default */
else if(code == 27) { /* ASCII ESCape */
user_response = TRUE; /* user wants opposite to default */
if(action == SYSB)
action = SYSA;
else
action = SYSB;
}
if(BLANKDONE) { /* if blank, unblank */
if(ia.reverse) {
SetRGB4(&BScreen->ViewPort,1,11,11,11);
}
else {
SetRGB4(&BScreen->ViewPort,1,0,0,0);
SetRGB4(&BScreen->ViewPort,0,8,9,9);
}
ClearPointer(BRWin); /* and bring back pointer */
}
BLANKDONE = FALSE; /* screen should no longer be blank */
blank_start = (int)seconds; /* reset blanker timer */
break;
}
}
}
}
/* take action either on user gadget selection or timeout default
*/
switch(action) {
case 1:
CleanUp();
system(ia.sysa);
break;
case 2:
if(ia.sysb == NULL)
CleanUp();
else {
CleanUp();
system(ia.sysb);
}
break;
}
}
/* clean up and return to calling environment
*/
void CleanUp(void) {
CloseWindow(BRWin);
CloseScreen(BScreen);
CloseLibrary((struct Library *)IntuitionBase);
CloseLibrary((struct Library *)DosBase);
CloseLibrary((struct Library *)GfxBase);
return;
}